package com.lh.aop;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.lh.base.ResResultCode;
import com.lh.exception.BadRequestException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 通过AOP和Knife4j对参数进行校验
 * 将每个有@DynamicParameters注解修饰的接口进行校验，对每个require=true的参数进行校验
 */
@Aspect
@Component
@Slf4j
public class ReqValidateAop {

    @Pointcut("@annotation(com.github.xiaoymin.knife4j.annotations.DynamicParameters)")
    public void paramValidate() {

    }

    @Before("paramValidate()")
    public void before(JoinPoint joinPoint) {
        List<String> errList = new ArrayList<>();
        // 获取传入目标方法的参数对象
        Object[] args = joinPoint.getArgs();
        JSONObject param = (JSONObject) args[0];
        // 获取当前方法
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();

        // 获取方法的@DynamicParameters 注解中的DynamicParameter集合
        DynamicParameters annotation = method.getAnnotation(DynamicParameters.class);
        List<DynamicParameter> dynamicParameters = Arrays.asList(annotation.properties());
        for (DynamicParameter dp : dynamicParameters) {
            // 必传参数校验
            if (dp.required()) {
                // 参数对象中根据名称取出对应的值
                Object o = param.get(dp.name());
                // 请求参数为null或请求参数为空或请求参数为空字符串
                if (o == null || (o instanceof String && StringUtils.isEmpty((String) o))) {
                    errList.add(dp.name() + "不能为空");
                }
            }
        }
        // 如果错误集合中不为空
        if (!errList.isEmpty()) {
            throw new BadRequestException(StrUtil.join(",", errList));
        }
    }

}
